package com.framework.websocket.service;

import com.framework.websocket.core.WebSocketManager;
import com.framework.websocket.utils.SpringContextUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.websocket.Session;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 心跳管理器
 */
@Slf4j
@Service
public class HeartbeatManager {
    
    @Value("${websocket.heartbeat.timeout:90000}")
    private long heartbeatTimeout;
    
    /**
     * 存储会话的最后心跳时间
     */
    private final Map<String, Long> sessionHeartbeatMap = new ConcurrentHashMap<>();
    
    /**
     * 处理心跳
     */
    public void handleHeartbeat(Session session) {
        sessionHeartbeatMap.put(session.getId(), System.currentTimeMillis());
        // 获取 WebSocketManager 实例
        WebSocketManager webSocketManager = SpringContextUtils.getBean(WebSocketManager.class);
        if (webSocketManager != null) {
            webSocketManager.sendMessage(session, "pong", null, null);
        }
        log.debug("收到心跳: {}", session.getId());
    }
    
    /**
     * 记录会话心跳
     */
    public void recordHeartbeat(Session session) {
        sessionHeartbeatMap.put(session.getId(), System.currentTimeMillis());
    }
    
    /**
     * 移除会话心跳记录
     */
    public void removeHeartbeat(Session session) {
        sessionHeartbeatMap.remove(session.getId());
    }
    
    /**
     * 定时检查心跳超时
     */
    @Scheduled(fixedDelay = 30000)
    public void checkHeartbeat() {
        long currentTime = System.currentTimeMillis();
        Iterator<Map.Entry<String, Long>> iterator = sessionHeartbeatMap.entrySet().iterator();
        
        while (iterator.hasNext()) {
            Map.Entry<String, Long> entry = iterator.next();
            if (currentTime - entry.getValue() > heartbeatTimeout) {
                log.warn("会话 {} 心跳超时", entry.getKey());
                iterator.remove();
                
                // 关闭超时的会话
                WebSocketManager webSocketManager = SpringContextUtils.getBean(WebSocketManager.class);
                if (webSocketManager != null) {
                    Session session = webSocketManager.getSession(entry.getKey());
                    if (session != null && session.isOpen()) {
                        try {
                            session.close();
                        } catch (Exception e) {
                            log.error("关闭超时会话失败", e);
                        }
                    }
                }
            }
        }
    }
}